/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/7/12 22:23
  *
  * @file       hd_oled_font.h
  * @brief      Header file of Xxx hardware driver.
  *
  * @note       This file contains the Xxx object declaration.
  *
  * @warning    None.
  ******************************************************************************
  * Change Logs:
  *   Date          Author       Notes
  *   2024/7/12     Chris        the first version
  *
  ******************************************************************************
  */


#ifndef JLC_SKY_OLED_FONT_H
#define JLC_SKY_OLED_FONT_H

#include "air001xx.h"
#include "hd_w25qxx.h"
#include "hd_storage.h"
#include "drivers.h"

typedef struct OLEDFontDef OLEDFont;

struct OLEDFontDef {
    /**
     * The Storage is a interface that provide dot matrix data. Storage can be any kind of
     * storage device as long as it can provide the OLED dot matrix data we need.
     * eg. W25Qxx, EEPROM, Flash, SDCard, etc.
     */
    Storage *storage;

    /**
     * the font's encoding, 0, GBK; 1, UTF-8
     */
    uint8_t encoding;

    void (*init)(OLEDFont *this);

    /**
     * Get a Dot Matrix data from a storage(Flash, SD card, etc.) through the font code and its size.
     *
     * @param dotMatrix a array that save the font's Dot Matrix data
     * @param font      a character for ASCII or Chinese
     * @param fontSize  the font size. it can be 12, 16, 24.
     */
    uint8_t (*getFontDotMatrix)(OLEDFont *this, uint8_t *dotMatrix, uint8_t *font, uint8_t fontSize);

};

extern const struct OLEDFontClass {
    OLEDFont *(*build)(Storage *storage, uint8_t encoding);
} OLEDFontBuilder;


#define ENCODING_GB2312     0
#define ENCODING_GBK        1
#define ENCODING_UTF8       2

/**
 * ASCII has 95 displayable character.
 * --------------------------------------------------------------------------------------
 * | Height * Width | display pixel | Graphic Memory(PAGE x SEG) | Bytes | font library |
 * |----------------|---------------|----------------------------|-------|--------------|
 * |    12 *  6     |   12 *  6     |          2 *  6            |  12   | 12*95=0x474  |
 * |    16 *  8     |   16 *  8     |          2 *  8            |  16   | 16*95=0x5F0  |
 * |    24 * 12     |   24 * 12     |          3 * 12            |  36   | 36*95=0xD5C  |
 * |------------------------------------------------------------------------------------|
 *
 * total 0x17C0(6080) bytes, about 6KB.
 */
#define STORAGE_ASCII_12X6_ADDRESS              0x00000000
#define STORAGE_ASCII_16X8_ADDRESS              0x00000000
#define STORAGE_ASCII_24X12_ADDRESS             0x00000000

/**
 * generate in range 0x4E00 ~ 0x9FFF from UNICODE
 */
#define STORAGE_UNICODE_CN_ZH_24X24_ADDRESS     0x0068D000  // 1480k(0x00172000)
#define STORAGE_UNICODE_CN_ZH_16X16_ADDRESS     0x005E8000  //  660k(0x000A5000)
#define STORAGE_UNICODE_CN_ZH_12X12_ADDRESS     0x0056B000  //  500k(0x0007D000)

/**
 * generate in range 0x8140 ~ 0xFEFF from gbk
 */
#define STORAGE_GBK_24X24_ADDRESS               0x003C4800  // 1690k(0x001A6800)
#define STORAGE_GBK_16X16_ADDRESS               0x00309000  //  750k(0x000BB800)
#define STORAGE_GBK_12X12_ADDRESS               0x0027A800  //  570k(0x0008E800)

/**
 * generate in range 0xA1A1 ~ 0xF7FF from gb2312
 */
#define STORAGE_GB2312_24X24_ADDRESS            0x001E9800  // 580k(0x00091000)
#define STORAGE_GB2312_16X16_ADDRESS            0x001A8800  // 260k(0x00041000)
#define STORAGE_GB2312_12X12_ADDRESS            0x00176800  // 200k(0x00032000)

#endif //JLC_SKY_OLED_FONT_H


